<?php
namespace app\admin\controller;

use app\admin\model\SystemAdmin;
use app\admin\model\SystemQuick;
use app\common\controller\AdminController;
use think\facade\Db;
use app\admin\controller\Curl;
use app\admin\model\DpjzUser;
use app\admin\model\DpjzSystem;
use think\facade\View;
use app\common\constants\CommonConstant;
use app\admin\model\DpjzLeader;
use app\common\service\XDecode;
use app\admin\model\DpjzRoom;

class Index extends AdminController
{

    /**
     * 后台主页
     *
     * @return string
     * @throws \Exception
     */
    public function index()
    {
        return $this->fetch('', [
            'admin' => session('admin')
        ]);
    }

    public function update_version()
    {
        $curl = new Curl();
        $curl->index();
    }

    public function version_view()
    {
        $curl = new Curl();
        $versions = $curl->version();
        
        return view('index/version', [
            'versions' => $versions
        ]);
    }

    public function upload_front()
    {
        $path = app()->getRootPath() . 'front';
        $filename = app()->getRootPath() . 'front';
        
        $this->create_zip($path, $filename);
        $this->downloadTemplate($filename . '.zip', date('Y-m-d') . '.zip');
    }

    public function create_zip($path, $filename)
    {
        $zip = new \ZipArchive();
        if ($zip->open($filename . '.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
            $this->addFileToZip($path, $zip);
            $zip->close(); // 关闭处理的zip文件
        }
    }

    function addFileToZip($path, $zip)
    {
        $handler = opendir($path);
        while (($filename = readdir($handler)) !== false) {
            if ($filename != "." && $filename != "..") {
                if (is_dir($path . "/" . $filename)) {
                    $this->addFileToZip($path . "/" . $filename, $zip);
                } else { // 将文件加入zip对象
                    $zip->addFile($path . "/" . $filename);
                }
            }
        }
        @closedir($path);
    }

    function downloadTemplate($path, $filename)
    {
        header("Content-type:text/html;charset=utf-8");
        if (! file_exists($path)) {
            echo "下载文件不存在！";
            exit();
        }
        
        $fp = fopen($path, "r");
        $file_size = filesize($path); // 获取文件的字节
                                      // 下载文件需要用到的头
        Header("Content-type: application/octet-stream");
        Header("Accept-Ranges: bytes");
        Header("Accept-Length:" . $file_size);
        Header("Content-Disposition: attachment; filename=$filename");
        $buffer = 1024; // 设置一次读取的字节数，每读取一次，就输出数据（即返回给浏览器）
        $file_count = 0; // 读取的总字节数
                         // 向浏览器返回数据 如果下载完成就停止输出，如果未下载完成就一直在输出。根据文件的字节大小判断是否下载完成
        while (! feof($fp) && $file_count < $file_size) {
            $file_con = fread($fp, $buffer);
            $file_count += $buffer;
            echo $file_con;
        }
        fclose($fp);
        // 下载完成后删除压缩包，临时文件夹
        if ($file_count >= $file_size) {
            unlink($path);
        }
    }

    /**
     * 后台欢迎页
     *
     * @return string
     * @throws \Exception
     */
    public function welcome()
    {
        $request = $this->request;
        
        $url = "http://c5.weijuyunke.com/api/softwareApi/newest_version";
        $host = $request->domain();
        $data = array(
            'rjbs' => 'figure_dl',
            'appid' => sysconfig("site", "site_appid"),
            'version' => sysconfig("site", "site_version"),
            'yuming' => $host
        );
        $result = json_decode(wtw_request($url, $data), true);
        
        $flag = 0;
        if ($result['code'] == '200') {
            $flag = 1;
        }
        
        $quicks = SystemQuick::field('id,title,icon,href')->where([
            'status' => 1
        ])
            ->order('sort', 'desc')
            ->limit(8)
            ->select();
        
        $user_count = DpjzUser::count();
        
        $cur_user_count = DpjzUser::where([
            [
                "create_time",
                ">=",
                strtotime(date("Y-m-d"))
            ],
            [
                "create_time",
                "<=",
                time()
            ]
        ])->count();
        $week_user_count = DpjzUser::where([
            [
                "create_time",
                ">=",
                strtotime("-7 days")
            ],
            [
                "create_time",
                "<=",
                time()
            ]
        ])->count();
        
        $room_count = DpjzRoom::count();
        
        $cur_room_count = DpjzRoom::where([
            [
                "create_time",
                ">=",
                strtotime(date("Y-m-d"))
            ],
            [
                "create_time",
                "<=",
                time()
            ]
        ])->count();
        $week_room_count = DpjzRoom::where([
            [
                "create_time",
                ">=",
                strtotime("-7 days")
            ],
            [
                "create_time",
                "<=",
                time()
            ]
        ])->count();
        
        $this->assign('quicks', $quicks);
        $this->assign('user_count', $user_count);
        $this->assign('room_count', $room_count);
        
        $this->assign('cur_user_count', $cur_user_count);
        $this->assign('week_user_count', $week_user_count);
        $this->assign('cur_room_count', $cur_room_count);
        $this->assign('week_room_count', $week_room_count);
        
        $mysql = Db::query('SELECT VERSION();');
        
        $php = phpversion();
        
        $mysql_version = $mysql[0]['VERSION()'];
        
        $system = DpjzSystem::where("id", 1)->find();
        if (! empty($system['domain']) && $request->domain() != $system['domain']) {
            $domain = $system['domain'];
        } else {
            $domain = $request->domain();
        }
        
        $this->assign('main_domain', $request->domain());
        $this->assign('domain', $domain);
        
        $this->assign('php', $php);
        $this->assign('mysql_version', $mysql_version);
        $this->assign('flag', $flag);
        
        return $this->fetch();
    }

    /**
     * 图表
     *
     * @return string
     * @throws \Exception
     */
    public function chart()
    {
        
        // data: ['用户新增', '房间新增']
        // 近七天
        $end_date = strtotime(date("Y-m-d") . ' +1 day');
        $dateList = array();
        $sql = "";
        for ($i = 7; $i >= 0; $i --) {
            $date = date('Y-m-d', intval(strtotime('-' . $i . ' day')));
            array_push($dateList, $date);
            if ($i == 7) {
                $start_time = $date;
                $sql .= "(
            SELECT
             '" . $date . "' AS date
            FROM DUAL ";
                continue;
            }
            $sql .= "UNION ALL
            SELECT 
             '" . $date . "' AS date
            FROM DUAL ";
        }
        $sql .= ")";
        
        // 用户新增
        $subQuery = Db::table("wjyk_dpjz_user")->where([
            [
                "create_time",
                ">=",
                strtotime($start_time)
            ],
            [
                "create_time",
                "<=",
                $end_date
            ]
        ])
            ->field("*,DATE_FORMAT(FROM_UNIXTIME(create_time),'%Y-%m-%d') day_time")
            ->buildSql();
        $secondQuery = Db::table($subQuery . ' a')->field("count(1) num,a.day_time")
            ->group('a.day_time')
            ->buildSql();
        
        $user_data = $this->dateJoin($secondQuery, $sql);
        
        // 房间新增
        $room_subQuery = Db::table("wjyk_dpjz_room")->where([
            [
                "create_time",
                ">=",
                strtotime($start_time)
            ],
            [
                "create_time",
                "<=",
                $end_date
            ]
        ])
            ->field("*,DATE_FORMAT(FROM_UNIXTIME(create_time),'%Y-%m-%d') day_time")
            ->buildSql();
        
        $room_secondQuery = Db::table($room_subQuery . ' a')->field("count(1)  num,a.day_time")
            ->group('a.day_time')
            ->buildSql();
        
        $room_data = $this->dateJoin($room_secondQuery, $sql);
        
        return msg([
            "dataList" => $dateList,
            "user_data" => $user_data,
            "room_data" => $room_data
        ], 0, "成功", 0);
    }

    /**
     * 腾讯请求
     */
    public function getQqLocationCity()
    {
        $ip = input("ip");
        
        $url = "https://apis.map.qq.com/ws/location/v1/ip?ip=" . $ip . "&key=TYQBZ-IGZCJ-E5XFU-KUR6C-OEGKZ-D2BLP&output=json";
        $data = wtw_request($url);
        /*
         * $curl = curl_init();
         * //设置url
         * curl_setopt($curl, CURLOPT_URL, $url);
         * // 不返回HTTP头部信息
         * curl_setopt($curl, CURLOPT_HEADER, false);
         * // 设置获取的信息以文件流的形式返回
         * curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
         * // 执行命令
         * $data = curl_exec($curl);
         */
        
        return json($data);
    }

    /**
     * 腾讯请求 模糊查询
     */
    public function getQqSuggestion()
    {
        $region = input("region");
        $keyword = input("keyword");
        $url = "https://apis.map.qq.com/ws/place/v1/suggestion?region=" . $region . "&keyword=" . $keyword . "&key=TYQBZ-IGZCJ-E5XFU-KUR6C-OEGKZ-D2BLP&output=json";
        $data = wtw_request($url);
        return json_decode($data);
    }

    /**
     * 日期连接查询
     *
     * @param sql $subQuery
     *            统计sql
     * @param sql $sql
     *            日期sql
     */
    private function dateJoin($subQuery, $sql)
    {
        $result = Db::table($subQuery . ' a')->rightJoin([
            $sql => 'w'
        ], "a.day_time=w.date")
            ->order("w.date", "asc")
            ->field("IFNULL(a.num,0) num")
            ->select();
        $data = array();
        foreach ($result as $k => $v) {
            array_push($data, $v['num']);
        }
        return $data;
    }

    /**
     * 日期连接查询
     *
     * @param sql $subQuery
     *            统计sql
     * @param sql $sql
     *            日期sql
     */
    private function orderDateJoin($subQuery, $sql)
    {
        $result = Db::table($subQuery . ' a')->rightJoin([
            $sql => 'w'
        ], "a.day_time=w.date")
            ->order("w.date", "asc")
            ->field("IFNULL(a.num,0) num,a.day_time")
            ->select()
            ->toArray();
        
        $obj = new XDecode(9);
        $data = array();
        foreach ($result as $k => $v) {
            
            if (! is_numeric($v['num'])) {
                $num = $obj->decode($v['num']);
                $v['num'] = round($num / 100, 2);
            }
            
            if (! empty($v['day_time'])) {
                
                $data = array_column($data, null, 'day_time');
                
                if ($this->deep_in_array($v['day_time'], $data)) {
                    $data[$v['day_time']]['num'] += $v['num'];
                } else {
                    array_push($data, array(
                        'day_time' => $v['day_time'],
                        'num' => empty($v['num']) ? "0.00" : $v['num']
                    ));
                }
            } else {
                array_push($data, array(
                    'day_time' => '',
                    'num' => "0.00"
                ));
            }
        }
        
        $num = array();
        foreach ($data as $k => $v) {
            array_push($num, round($v['num'], 2));
        }
        
        return $num;
    }

    function deep_in_array($value, $array)
    {
        foreach ($array as $item) {
            if (! is_array($item)) {
                if ($item == $value) {
                    return true;
                } else {
                    continue;
                }
            }
            if (in_array($value, $item)) {
                return true;
            } elseif ($this->deep_in_array($value, $item)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 修改管理员信息
     *
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function editAdmin()
    {
        $id = session('admin.id');
        $row = (new SystemAdmin())->withoutField('password')->find($id);
        empty($row) && $this->error('用户信息不存在');
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $this->isDemo && $this->error('演示环境下不允许修改');
            $rule = [];
            $this->validate($post, $rule);
            try {
                $save = $row->allowField([
                    'head_img',
                    'phone',
                    'remark',
                    'update_time'
                ])->save($post);
            } catch (\Exception $e) {
                $this->error('保存失败');
            }
            $save ? $this->success('保存成功') : $this->error('保存失败');
        }
        $this->assign('row', $row);
        return $this->fetch();
    }

    /**
     * 修改密码
     *
     * @return string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function editPassword()
    {
        $id = session('admin.id');
        $row = (new SystemAdmin())->withoutField('password')->find($id);
        if (! $row) {
            $this->error('用户信息不存在');
        }
        if ($this->request->isPost()) {
            $post = $this->request->post();
            $this->isDemo && $this->error('演示环境下不允许修改');
            $rule = [
                'password|登录密码' => 'require',
                'password_again|确认密码' => 'require'
            ];
            $this->validate($post, $rule);
            if ($post['password'] != $post['password_again']) {
                $this->error('两次密码输入不一致');
            }
            
            try {
                $save = $row->save([
                    'password' => password($post['password'])
                ]);
            } catch (\Exception $e) {
                $this->error('保存失败');
            }
            if ($save) {
                $this->success('保存成功');
            } else {
                $this->error('保存失败');
            }
        }
        $this->assign('row', $row);
        return $this->fetch();
    }
}
